# GNAFU - "Ground, Navy and Air Fuck-Up" real-time strategy game
# Copyright (C) 2008-2009 k0wax <k0waxk0wax@gmail.com>
#
# This file is part of GNAFU.
#
# GNAFU is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# GNAFU is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GNAFU.  If not, see <http://www.gnu.org/licenses/>.

"""Game base infrastructure"""
from __future__ import division, absolute_import
import weakref
import pyglet
from src import conf, vars, geom, field
from src.pathfind import path
from src import game

class UnitController(pyglet.event.EventDispatcher):
    """Unit's game subsystem operations (controller). Not a unit's model controller.
    note: controller or a subsystem?
    """
    units = []
    selected_units = []
    def get_all_units(self):
        return self.units
    def get_units_rect(self, x, y, w, h):
        """Return units list by given rect
        """
        return [o for o in self.get_all_units() if geom.in_rect(o.x, o.y, x, y, w, h)]
    def kill_unit(self, unit):
        """Unit.kill(u)
        """
        #_destroy(unit)
        return self.dispatch_event('on_unit_kill', unit)
    def create_unit(self, x, y):
        u = unit.New()
        u.x = x
        u.y = y
        return self.dispatch_event('on_unit_create', u)
    def on_unit_move_to(self, unit, cx, cy):
        print 'game.ctl callback handled (on_unit_move_to)', unit, cx, cy
    def get_selected_units(self):
        return self.selected_units
    def unselect_all(self):
        self.selected_units = []
    def on_unit_create(self, u):
        self.units.append(u)
        print 'ILOLD', u
    def unit_select(self, u):
        self.selected_units.append(u)
    def unit_unselect(self, u):
        self.selected_units.remove(u)
    def on_hud_click(self, x, y, buttons, modifiers):
        from src import inp
        for u in self.get_selected_units():
            u.move_to(inp.m.cx, inp.m.cy)
    def _update(self, dt): # XXX FIXME inheritance super call fail, inf loop
        for u in self.get_all_units():
            u.update(dt)
    def move_to(self, cx, cy):
        """controller function"""
        zmin, zmax = field.surface_minmax_levels[self.surface_type]
        if game.field.zlevel[cx][cy] in xrange(zmin, zmax+1): # fixme
            self.path = path((self.cx, self.cy), (cx, cy), surface_type=self.surface_type)
            print self.path
            return True
        else:
            return False
        return self.dispatch_event('on_unit_move_to', self, cx, cy)

class SFXController(object):
    """SFX test controller"""
    def on_unit_create(self, u):
        print 'PLAY SFX for', u

class ViewportController(object):
    pass

class GameController(pyglet.event.EventDispatcher):
    """Game controller/handler and event dispatcher
    """
    def __init__(self):
        self.sfxctl = SFXController()
        self.push_handlers(self.sfxctl)
    def on_building_create(self, b):
        print 'LOLOLOLOOLOLOL', b
    def on_viewport_scroll(self, rect):
        """Handle viewport scrolling
        """
        print 'game controller: on viewport scroll'
        '''Piece of general GAME LOGIC HERE'''
        for o in game.unitctl.get_all_units():
            if geom.in_rect(o.x, o.y, *rect):
                o.visible = True
                print 'set visible', o.x, o.y
            else:
                o.visible = False
    def on_hud_selection_update(self, rect):
        game.unitctl.unselect_all()
        for u in game.unitctl.get_units_rect(*rect):
            game.unitctl.unit_select(u)
        print 'lol', rect, game.unitctl.get_selected_units()
    def on_hud_click(self, x, y, buttons, modifiers):
        for b in game.buildingctl.get_visible_buildings():
            if geom.hit_test(b.rect, x, y):
                b.on_click()

event_types = """
on_viewport_scroll
on_hud_click
""".split()

#on_building_create
for event_type in event_types:
    GameController.register_event_type(event_type)

UnitController.register_event_type('on_unit_create')
UnitController.register_event_type('on_unit_move_to')

"""
Unit.self.ctl.kill -> self.ctl do game related logic (conditions checks, land check, etc. then set new state of the model) ->
send on_unit_kill to game.ctl -> game.ctl do third party connected logic (calls to other system modules, like sfx playing)

"""
